/*
 * threads functions
 */



#include <pthread.h>

int pthread_equal(pthread_t t1, pthread_t t2);

/*
 * Complie and link with -pthread.
 *
 * RETURN VALUE
 *      If the two thread IDs are equal, pthread_equal() returns a nonzero
 *      value; otherwise, it returns 0.
 *
 * ERRORS
 *      This function always succeeds.
 */




#include <pthread.h>

pthread_t pthread_self(void);

/*
 * RETURN VALUE
 *      This function always succeeds, returning the calling thread's ID.
 *
 * ERRORS
 *      This function always succeeds.
 */




#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg);

/*
 * RETURN VALUE
 *      On success, pthread_create() returns 0; on error, it returns an error
 *      number, and the contents of *thread are undefined.
 *
 * ERRORS
 *      EAGAIN  Insufficient resources to create another thread, or a
 *              system-imposed limit on the number of threads was encountered. 
 *              The later case may occur in two ways the RLIMIT_NPROC soft
 *              resource limit (set via setrlimit), which limits the number 
 *              of process for a real user ID, was reached; or the kernel's
 *              system-wide limit on the number of threads,
 *              /proc/sys/kernel/threads-max, was reached.
 *      EINVAL  Invalid settings in attr.
 *      EPERM   No permission to set the scheduling policy and parameters
 *              specified in attr.
 */




#include <pthread.h>

void pthread_exit(void *retval);

/*
 * RETURN VALUE
 *      This function does not return to the caller.
 *
 * ERRORS
 *      This function always succeeds.
 */




#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);

/*
 * RETURN VALUE
 *      On success, pthread_join() returns 0; on error, it returens an
 *      error number.
 *
 * ERRORS
 *      EDEADLK A deadlock was detected (e.g., two threads tried to join
 *              with each other); or thread specifies the calling thread.
 *      EINVAL  thread is not a joinable thread.
 *      EINVAL  Another thread is already waiting to join with this thread.
 *      ESRCH   No thread with the ID thread could be found.
 */




#include <pthread.h>

int pthread_detach(pthread_t thread);

/*
 * RETURN VALUE
 *      On success, pthread_detach() returns 0; on error, it returns an
 *      error number.
 *
 * ERRORS
 *      EINVAL  thread is not a joinable thread.
 *      ESRCH   No thread with the ID thread could be found.
 */



#include <pthread.h>

int pthread_cancel(pthread_t thread);

/*
 * RETURN VALUE
 *      On success, pthread_cancel() returns 0; on error, it returns a
 *      nonzero error number.
 *
 * ERRORS
 *      ESRCH   No thread with the ID thread could be found.
 */




#include <pthread.h>

void pthread_cleanup_push(void (*routine)(void *), void *arg);

void pthread_cleanup_pop(int execute);

/*
 * RETURN VALUE
 *      These functions do not return a value.
 *
 * ERRORS
 *      There are no errors.
 */




#include <pthread.h>

pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_UP;

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

int pthread_mutex_destroy(pthread_mutex_t *mutex);

/* RETURN VALUE
 *      pthead_mutex_init always returns 0. The other mutex functions
 *      return 0 on success and a non-zero error code on error.
 *
 * ERRORS
 *      The phtread_mutex_lock function returns the following error
 *      codes on error:
 *          EINVAL  
 *              the mutex has not been properly initialized.
 *          EDEADLK 
 *              the mutex is already locked by the calling thread
 *              (''error checking'' mutexes only).
 *
 *      The pthread_mutex_trylock function returns the following error
 *      codes on error:
 *          EBUSY
 *              the mutex could not be acquired because it was currently
 *              locked.
 *          EINVAL
 *              the mutex has not been properly initialized.
 *
 *      The pthread_mutex_unlock function returns the following error
 *      codes on error:
 *          EINVAL
 *              the mutex has not been properly initialized.
 *          EPERM
 *              the calling thread does not own the mutex
 *              (''error checking'' mutexes only).
 *
 *      The pthread_mutex_destroy function returns the following error
 *      code on error:
 *          EBUSY
 *              the mutex is currently locked.
 */



#include <pthread.h>
#include <time.h>

int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,
        const struct timespec *restrict abs_timeout);

/*
 * RETURN VALUE
 *      If successful, the pthread_mutex_timedlock() function shall return
 *      zero; otherwise, an error number shall be returned to indicate
 *      the error.
 *
 * ERRORS
 *      The pthread_mutex_timedlock() function shall fail if:
 *          EINVAL
 *              The mutex was created with the protocol attribute having the
 *              value PTHREAD_PRIO_PROTECT and the calling thread's priority
 *              is higher than the mutex' current priority ceiling.
 *          EINVAL
 *              The process or thread would have blocked, and the abs_timeout
 *              parameter specified a nanoseconds field value less than zero
 *              or greater than or equeal to 1000 millon.
 *          ETIMEOUT
 *              The mutex could not be locked before the specified timeout
 *              expired.
 *
 *      The pthread_mutex_timedlock() function may fail if:
 *          EINVAL
 *              The value specified by mutex does not refer to an initialized
 *              mutex object.
 *          EAGAIN
 *              The mutex could not be acquired because the maximum number of
 *              recursive locks for mutex has been exceeded.
 *          EDEADLK
 *              The current thread already owns the mutex.
 *
 *      This function shall not return an error code of [EINTR].
 */




#include <pthread.h>

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
        const pthread_rwlockattr_t *restrict attr);

/*
 * RETURN VALUE
 *      If successful, the pthread_rwlock_destroy() and pthread_rwlock_init()
 *      functions shall return zero; otherwise, an error number shall be
 *      returned to indicate the error.
 *
 *      The [EBUSY] and [EINVAL] error checks, if implemented, act as if they
 *      were performed immediately at the beginning of processing for the
 *      function and caused an error return prior to modifying the state of
 *      the read-write lock specified by rwlock.
 *
 * ERRORS
 *      The pthread_rwlock_destroy() function may fail if:
 *
 *      EBUSY   The implementation has detected an attempt to destroy the
 *              object referenced by rwlock while it is locked.
 *
 *      EINVAL  The value specified by rwlock is invalid.
 *
 *      The pthread_rwlock_init() function shall fail if:
 *
 *      EAGAIN  The system lacked the necessary resources (other than memory)
 *              to initialize another read-write lock.
 *
 *      ENOMEM  Insufficient memory exists to initialize the read-write lock.
 *
 *      EPERM   The caller does not have the privilege to perform the 
 *              operation.
 *
 *      The pthread_rwlock_init() function may fail if:
 *
 *      EBUSY   The implementation has detected an attempt to reinitialize the
 *              object referenced by rwlock, a previously initialized but not
 *              yet destroyed read-write lock.
 *
 *      EINVAL  The value specified by attr is invalid.
 *
 *      These functions shall not return an error code of [EINTR].
 */




#include <pthread.h>

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

/*
 * RETURN VALUE
 *      If successful, the pthread_rwlock_rdlock() function shall return zero;
 *      otherwise, an error number shall be returned to indicate the error.
 *
 *      The pthread_rwlock_tryrdlock() function shall return zero if the lock
 *      for reading on the read-write lock object referenced by rwlock is
 *      acquired. Otherwise, an error number shall be returned to indicate
 *      the error.
 *
 * ERRORS
 *      The pthread_rwlock_tryrdlock() function shall fail if:
 *
 *      EBUSY   The read-write lock could not be acquired for reading because
 *              a writer holds the lock or a writer with the appropriate
 *              priority was blocked on it.
 *
 *      The pthread_rwlock_rdlock() and pthread_rwlock_tryrdlock() functions
 *      may fail if:
 *
 *      EINVAL  The value specified by rwlock does not refer to an initialized
 *              read-write lock object.
 *
 *      EAGAIN  The read lock could not be acquired because the maximux number
 *              of read locks for rwlock has been exceeded.
 *
 *      The pthread_rwlock_rdlock() function may fail if:
 *
 *      EDEADLK The current thread already owns the read-write lock for
 *              writting.
 */




#include <pthread.h>

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

/*
 * RETURN VALUE
 *      The pthread_rwlock_trywrlock() function shall return zero if the lock
 *      for writing on the read-write lock object referenced by rwlock is
 *      acquired. Otherwis, an error number shall be returned to indicate
 *      the error.
 *
 *      If successful, the pthread_rwlock_wrlock() function shall return zero;
 *      otherwise, an error number shall be returned to indicate the error.
 *
 * ERRORS
 *      The pthread_rwlock_trywrlock() function shall fail if:
 *
 *      EBUSY   The read-write lock could not be acquired for writing because
 *              it was already locked for reading or writing.
 *
 *      The pthread_rwlock_trywrlock() and pthread_rwlock_wrlock() functions
 *      may fail if:
 *
 *      EINVAL  The value specified by rwlock does not refer to an initialized
 *              read-write lock object.
 *
 *      The pthread_rwlock_wrlock() function may fail if:
 *
 *      EDEADLK The current thread already owns the read-write lock for
 *              writing or reading.
 *
 *      These functions shall not return an error code of [EINTR].
 */




#include <pthread.h>

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);

int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
        const struct timespec *abstime);

int pthread_cond_destroy(pthread_cond_t *cond);

/*
 * RETURN VALUE
 *      All condition variable functions return 0 on success and a non-zero
 *      error code on error.
 *
 * ERRORS
 *      pthread_cond_init, pthread_cond_signal, pthread_cond_broadcast, and
 *      pthread_cond_wait never return an error code.
 *
 *      The pthread_cond_timedwait function returns the following error codes
 *      on error:
 *
 *          ETIMEDOUT
 *              the condition variable was not signaled until the timeout
 *              speceified by abstime
 *
 *          EINTR
 *              pthread_cond_timedwait was interrupted by a signal
 *
 *      The pthread_cond_destroy function returns the following error code
 *      on error:
 *          
 *          EBUSY
 *              some threads are currently wait on cond
 */




#include <pthread.h>

int pthread_spin_init(pthread_spinlock_t *lock, int pshared);

int pthread_spin_destroy(pthread_spinlock_t *lock);

/*
 * RETURN VALUE
 *      Upon successful completion, these functions shall return zero;
 *      otherwise, an error number shall be returned to indicate the error.
 *
 * ERRORS
 *      These functions may fail if:
 *
 *      EBUSY   The implementation has detected an attempt to initialize or
 *              destroy a spin lock while it is in user (for example, while
 *              being used in a pthread_spin_lock() call) by another thread.
 *
 *      EINVAL  The value specified by lock is invalid.
 *
 *      The pthread_spin_init() function shall fail if:
 *
 *      EAGAIN  The system lacks the necessary resources to initialize
 *              another spin lock.
 *
 *      ENOMEM  Insufficient memory exists to initialize the lock.
 *      
 *      These functions shall not return an error code of [EINTR].
 */




#include <pthread.h>

int pthread_spin_lock(pthread_spinlock_t *lock);

int pthread_spin_trylock(pthread_spinlock_t *lock);

/*
 * RETURN VALUE
 *      Upon successful completion, these functions shall return zero;
 *      otherwise, an error number shall be returned to indicate the error.
 *
 * ERRORS
 *      These functions may fail if:
 *
 *      EINVAL  The value specified by lock does not refer to an initialized
 *              spin lock object.
 *
 *      The pthread_spin_lock() function may fail if:
 *
 *      EDEADLK The calling thread already holds the lock.
 *
 *      The pthread_spin_trylock() function shall fail if:
 *
 *      EBUSY   A thread currently holds the lock.
 *
 *      These funcations shall not return an error code of [EINTR].
 */




#include <pthread.h>

int pthread_spin_unlock(pthread_spinlock_t *lock);

/*
 * RETURN VALUE
 *      Upon successful completion, the pthread_spin_unlock() function shall
 *      return zero; otherwise, an error number shall be returned to indicate
 *      the error.
 *
 * ERRORS
 *      The pthread_spin_unlock() function may fail if:
 *
 *      EINVAL  An invalid argument was specified.
 *
 *      EPERM   The calling thread does not hold the lock.
 *
 *      This function shall not return an error code of [EINTR].
 */




#include <pthread.h>

int pthread_barrier_destroy(pthread_barrier_t *barrier);

int pthread_barrier_init(pthread_barrier_t *restrice barrier,
        const pthread_barrierattr_t *restrict attr, unsigned count);

/*
 * RETURN VALUE
 *      Upon successful completion, these functions shall return zero;
 *      otherwise, an error number shall be returned to indicate the error.
 *
 * ERRORS
 *      The pthread_barrier_destroy() function may fail if:
 *
 *      EBUSY   The implementation has detected an attempt to destroy a
 *              barrier while it is in use (for example, while being used
 *              in a pthread_barrier_wait() call) by another thread.
 *
 *      EINVAL  The value specified by barrier is invalid.
 *
 *      The pthread_barrier_init() function shall fail if:
 *
 *      EAGAIN  The system lacks the necessary resources to initialize
 *              another barrier.
 *
 *      EINVAL  The value specified by count is equal to zero.
 *
 *      ENOMEM  Insufficient memory exists to initialize the barrier.
 *
 *      The pthread_barrier_init() function may fail if:
 *
 *      EBUSY   The implementation has detected an attempt to reinitialize
 *              a barrier while it is in use (for example, while being used
 *              in a pthread_barrier_wait() call) by another thread.
 *
 *      EINVAL  The value specified by attr is invalid.
 *
 *      These functions shall not return an error code of [EINTR].
 */




#include <pthread.h>

int pthread_barrier_wait(pthread_barrier_t *barrier);

/*
 * RETURN VALUE
 *      Upon successful completion, the pthread_barrier_wait() function shall
 *      return PTHREAD_BARRIER_SERIAL_THREAD for a single (arbitrary) thread
 *      synchronized at the barrier and zero for each of the other thread.
 *      Otherwise, an error number shall be returned to indicate the error.
 *
 * ERRORS
 *      The pthread_barrier_wait() function may fail if:
 *
 *      EINVAL  The value specified by barrier does not refer to an
 *              initialized barrier object.
 *
 *      This function shall not return an error code of [EINTR].
 */
